﻿namespace FTchina.Library
{
    using System;
    using System.Globalization;
    using System.Management;
    using System.Net;
    using System.Runtime.InteropServices;
    using System.Text;

    public class Win32Util
    {
        private const int EWX_FORCE = 4;
        private const int EWX_FORCEIFHUNG = 0x10;
        private const int EWX_LOGOFF = 0;
        private const int EWX_POWEROFF = 8;
        private const int EWX_REBOOT = 2;
        private const int EWX_SHUTDOWN = 1;
        public static Random random = new Random();
        private const int SE_PRIVILEGE_ENABLED = 2;
        private const string SE_SHUTDOWN_NAME = "SeShutdownPrivilege";
        private const int TOKEN_ADJUST_PRIVILEGES = 0x20;
        private const int TOKEN_QUERY = 8;

        public static long Address(IPAddress address)
        {
            byte[] addressBytes = address.GetAddressBytes();
            if (addressBytes.Length < 8)
            {
                return (long)BitConverter.ToUInt32(addressBytes, 0);
            }
            return (long)BitConverter.ToUInt64(addressBytes, 0);
        }

        [DllImport("advapi32.dll", SetLastError = true, ExactSpelling = true)]
        private static extern bool AdjustTokenPrivileges(IntPtr htok, bool disall, ref Luid newst, int len, IntPtr prev, IntPtr relen);
        [DllImport("gdi32.dll")]
        private static extern ulong BitBlt(IntPtr hDestDC, int x, int y, int nWidth, int nHeight, IntPtr hSrcDC, int xSrc, int ySrc, int dwRop);
        private static void DoExitWindows(int flg)
        {
            Luid luid;
            IntPtr currentProcess = GetCurrentProcess();
            IntPtr zero = IntPtr.Zero;
            OpenProcessToken(currentProcess, 40, ref zero);
            luid.count = 1;
            luid.luid = 0L;
            luid.attr = 2;
            LookupPrivilegeValue(null, "SeShutdownPrivilege", ref luid.luid);
            AdjustTokenPrivileges(zero, false, ref luid, 0, IntPtr.Zero, IntPtr.Zero);
            ExitWindowsEx(flg, 0);
        }

        [DllImport("user32.dll", SetLastError = true, ExactSpelling = true)]
        private static extern bool ExitWindowsEx(int flg, int rea);
        [DllImport("user32.dll")]
        private static extern IntPtr FindWindow(string className, string windowName);
        [DllImport("user32.dll")]
        private static extern IntPtr FindWindowEx(IntPtr parent, IntPtr childAfter, string className, string windowName);
        public static byte[] GetAdapterAddress()
        {
            NCB ncb = new NCB();
            ASTAT structure = new ASTAT();
            ncb.ncb_command = 50;
            ncb.ncb_lana_num = 0;
            byte num = Netbios(ref ncb);
            ncb.init();
            ncb.ncb_command = 0x33;
            ncb.ncb_lana_num = 0;
            ncb.ncb_callname1 = 0x2a;
            ncb.ncb_callname2 = 0x20;
            ncb.ncb_callname3 = 0x20;
            ncb.ncb_callname4 = 0x20;
            ncb.ncb_callname5 = 0x20;
            ncb.ncb_callname6 = 0x20;
            ncb.ncb_callname7 = 0x20;
            ncb.ncb_callname8 = 0x20;
            ncb.ncb_callname9 = 0x20;
            ncb.ncb_callname10 = 0x20;
            ncb.ncb_callname11 = 0x20;
            ncb.ncb_callname12 = 0x20;
            ncb.ncb_callname13 = 0x20;
            ncb.ncb_callname14 = 0x20;
            ncb.ncb_callname15 = 0x20;
            ncb.ncb_callname16 = 0x20;
            IntPtr ptr = Marshal.AllocHGlobal(Marshal.SizeOf(structure));
            Marshal.StructureToPtr(structure, ptr, true);
            ncb.ncb_buffer = ptr;
            ncb.ncb_length = 240;
            if (Netbios(ref ncb) == 0)
            {
                ASTAT astat2 = (ASTAT)Marshal.PtrToStructure(ptr, typeof(ASTAT));
                return new byte[] { astat2.adapt.adapter_address1, astat2.adapt.adapter_address2, astat2.adapt.adapter_address3, astat2.adapt.adapter_address4, astat2.adapt.adapter_address5, astat2.adapt.adapter_address6 };
            }
            return new byte[0];
        }

        public static string GetCpuID()
        {
            try
            {
                string str = "";
                ManagementObjectCollection instances = new ManagementClass("Win32_Processor").GetInstances();
                foreach (ManagementObject obj2 in instances)
                {
                    str = obj2.Properties["ProcessorId"].Value.ToString();
                }
                instances = null;
                return str;
            }
            catch
            {
                return "unknow";
            }
        }

        [DllImport("kernel32.dll", ExactSpelling = true)]
        private static extern IntPtr GetCurrentProcess();
        [DllImport("user32.dll")]
        private static extern IntPtr GetDesktopWindow();
        public static string GetDiskID()
        {
            try
            {
                string str = "";
                ManagementObjectCollection instances = new ManagementClass("Win32_DiskDrive").GetInstances();
                foreach (ManagementObject obj2 in instances)
                {
                    str = (string)obj2.Properties["Model"].Value;
                }
                instances = null;
                return str;
            }
            catch
            {
                return "unknow";
            }
        }

        public static string GetExploreUrl()
        {
            IntPtr parent = FindWindow("IEFrame", null);
            if (parent != IntPtr.Zero)
            {
                string className = "";
                if (Environment.OSVersion.Platform == PlatformID.Win32NT)
                {
                    className = "WorkerW";
                }
                else
                {
                    className = "WorkerA";
                }
                IntPtr window = FindWindowEx(FindWindowEx(FindWindowEx(FindWindowEx(FindWindowEx(parent, IntPtr.Zero, className, null), IntPtr.Zero, "ReBarWindow32", null), IntPtr.Zero, "ComboBoxEx32", null), IntPtr.Zero, "ComboBox", null), IntPtr.Zero, "Edit", null);
                StringBuilder text = new StringBuilder(0xff);
                SendMessage(window, 13, 0xff, text);
                return text.ToString();
            }
            return "";
        }

        public static byte[] GetMacAddress()
        {
            try
            {
                string str = "";
                ManagementObjectCollection instances = new ManagementClass("Win32_NetworkAdapterConfiguration").GetInstances();
                foreach (ManagementObject obj2 in instances)
                {
                    if ((bool)obj2["IPEnabled"])
                    {
                        str = obj2["MacAddress"].ToString();
                        break;
                    }
                }
                instances = null;
                if (str != "")
                {
                    string[] strArray = str.Split(new char[] { ':' });
                    byte[] buffer = new byte[strArray.Length];
                    for (int i = 0; i < buffer.Length; i++)
                    {
                        buffer[i] = byte.Parse(strArray[i], NumberStyles.HexNumber);
                    }
                    return buffer;
                }
                return new byte[0];
            }
            catch
            {
                return new byte[0];
            }
        }

        public static int GetRandomInt32()
        {
            return random.Next(0x7fffffff);
        }

        public static long GetRandomInt64()
        {
            long num = random.Next(0x7fffffff);
            long num2 = random.Next(0x7fffffff);
            return ((num << 0x20) | num2);
        }

        public static string GetRemoteMac(string dest, string host)
        {
            int num = inet_addr(dest);
            int num2 = inet_addr(host);
            long mac = 0L;
            int length = 6;
            int num5 = SendARP(num, num2, ref mac, ref length);
            byte[] bytes = BitConverter.GetBytes(mac);
            string str = bytes[0].ToString("X2");
            for (int i = 1; i < 6; i++)
            {
                str = str + ":" + bytes[i].ToString("X2");
            }
            return str;
        }

        public static string GetUserName()
        {
            try
            {
                string str = "";
                ManagementObjectCollection instances = new ManagementClass("Win32_ComputerSystem").GetInstances();
                foreach (ManagementObject obj2 in instances)
                {
                    str = obj2["UserName"].ToString();
                }
                instances = null;
                return str;
            }
            catch
            {
                return "unknow";
            }
        }

        [DllImport("user32.dll")]
        private static extern IntPtr GetWindowDC(IntPtr hwnd);
        [DllImport("ws2_32.dll")]
        private static extern int inet_addr(string ip);
        public static void LockTheComputer()
        {
            LockWorkStation();
        }

        [DllImport("user32.dll", ExactSpelling = true)]
        private static extern bool LockWorkStation();
        public static void LogOff()
        {
            DoExitWindows(0);
        }

        [DllImport("advapi32.dll", SetLastError = true)]
        private static extern bool LookupPrivilegeValue(string host, string name, ref long pluid);
        [DllImport("netapi32.dll")]
        public static extern byte Netbios(ref NCB ncb);
        [DllImport("advapi32.dll", SetLastError = true)]
        private static extern bool OpenProcessToken(IntPtr h, int acc, ref IntPtr phtok);
        public static void Restart()
        {
            DoExitWindows(6);
        }

        [DllImport("iphlpapi.dll")]
        private static extern int SendARP(int dest, int host, ref long mac, ref int length);
        [DllImport("user32.dll")]
        private static extern int SendMessage(IntPtr window, int message, int wparam, [Out] StringBuilder text);
        public static void Shutdown()
        {
            DoExitWindows(5);
        }

        [StructLayout(LayoutKind.Explicit, Size = 60)]
        public struct ADAPTER_STATUS
        {
            [FieldOffset(0)]
            public byte adapter_address1;
            [FieldOffset(1)]
            public byte adapter_address2;
            [FieldOffset(2)]
            public byte adapter_address3;
            [FieldOffset(3)]
            public byte adapter_address4;
            [FieldOffset(4)]
            public byte adapter_address5;
            [FieldOffset(5)]
            public byte adapter_address6;
            [FieldOffset(8)]
            public byte adapter_type;
            [FieldOffset(10)]
            public ushort duration;
            [FieldOffset(40)]
            public ushort free_ncbs;
            [FieldOffset(12)]
            public ushort frmr_recv;
            [FieldOffset(14)]
            public ushort frmr_xmit;
            [FieldOffset(0x10)]
            public ushort iframe_recv_err;
            [FieldOffset(0x1c)]
            public ushort iframe_xmit_err;
            [FieldOffset(0x2a)]
            public ushort max_cfg_ncbs;
            [FieldOffset(0x34)]
            public ushort max_cfg_sess;
            [FieldOffset(0x30)]
            public ushort max_dgram_size;
            [FieldOffset(0x2c)]
            public ushort max_ncbs;
            [FieldOffset(0x36)]
            public ushort max_sess;
            [FieldOffset(0x38)]
            public ushort max_sess_pkt_size;
            [FieldOffset(0x3a)]
            public ushort name_count;
            [FieldOffset(50)]
            public ushort pending_sess;
            [FieldOffset(30)]
            public ushort recv_buff_unavail;
            [FieldOffset(0x18)]
            public uint recv_success;
            [FieldOffset(7)]
            public byte reserved0;
            [FieldOffset(0x24)]
            public uint reserved1;
            [FieldOffset(6)]
            public byte rev_major;
            [FieldOffset(9)]
            public byte rev_minor;
            [FieldOffset(0x20)]
            public ushort t1_timeouts;
            [FieldOffset(0x22)]
            public ushort ti_timeouts;
            [FieldOffset(0x12)]
            public ushort xmit_aborts;
            [FieldOffset(0x2e)]
            public ushort xmit_buf_unavail;
            [FieldOffset(20)]
            public uint xmit_success;
        }

        [StructLayout(LayoutKind.Explicit, Size = 240)]
        private struct ASTAT
        {
            [FieldOffset(0)]
            public Win32Util.ADAPTER_STATUS adapt;
            [FieldOffset(60)]
            public Win32Util.NAME_BUFFER NameBuff1;
            [FieldOffset(0xde)]
            public Win32Util.NAME_BUFFER NameBuff10;
            [FieldOffset(0x4e)]
            public Win32Util.NAME_BUFFER NameBuff2;
            [FieldOffset(0x60)]
            public Win32Util.NAME_BUFFER NameBuff3;
            [FieldOffset(0x72)]
            public Win32Util.NAME_BUFFER NameBuff4;
            [FieldOffset(0x84)]
            public Win32Util.NAME_BUFFER NameBuff5;
            [FieldOffset(150)]
            public Win32Util.NAME_BUFFER NameBuff6;
            [FieldOffset(0xa8)]
            public Win32Util.NAME_BUFFER NameBuff7;
            [FieldOffset(0xba)]
            public Win32Util.NAME_BUFFER NameBuff8;
            [FieldOffset(0xcc)]
            public Win32Util.NAME_BUFFER NameBuff9;
        }

        [StructLayout(LayoutKind.Sequential, Pack = 1)]
        public struct Luid
        {
            public int count;
            public long luid;
            public int attr;
        }

        [StructLayout(LayoutKind.Explicit, Size = 0x12)]
        public struct NAME_BUFFER
        {
            [FieldOffset(0x11)]
            public byte name_flags;
            [FieldOffset(0x10)]
            public byte name_num;
            [FieldOffset(0)]
            public long name1;
            [FieldOffset(8)]
            public long name2;
        }

        [StructLayout(LayoutKind.Explicit, Size = 0x40)]
        public struct NCB
        {
            [FieldOffset(4)]
            public IntPtr ncb_buffer;
            [FieldOffset(10)]
            public byte ncb_callname1;
            [FieldOffset(0x13)]
            public byte ncb_callname10;
            [FieldOffset(20)]
            public byte ncb_callname11;
            [FieldOffset(0x15)]
            public byte ncb_callname12;
            [FieldOffset(0x16)]
            public byte ncb_callname13;
            [FieldOffset(0x17)]
            public byte ncb_callname14;
            [FieldOffset(0x18)]
            public byte ncb_callname15;
            [FieldOffset(0x19)]
            public byte ncb_callname16;
            [FieldOffset(11)]
            public byte ncb_callname2;
            [FieldOffset(12)]
            public byte ncb_callname3;
            [FieldOffset(13)]
            public byte ncb_callname4;
            [FieldOffset(14)]
            public byte ncb_callname5;
            [FieldOffset(15)]
            public byte ncb_callname6;
            [FieldOffset(0x10)]
            public byte ncb_callname7;
            [FieldOffset(0x11)]
            public byte ncb_callname8;
            [FieldOffset(0x12)]
            public byte ncb_callname9;
            [FieldOffset(0x31)]
            public byte ncb_cmd_cplt;
            [FieldOffset(0)]
            public byte ncb_command;
            [FieldOffset(60)]
            public uint ncb_event;
            [FieldOffset(0x30)]
            public byte ncb_lana_num;
            [FieldOffset(8)]
            public ushort ncb_length;
            [FieldOffset(2)]
            public byte ncb_lsn;
            [FieldOffset(0x1a)]
            public long ncb_name1;
            [FieldOffset(0x22)]
            public long ncb_name2;
            [FieldOffset(3)]
            public byte ncb_num;
            [FieldOffset(0x2c)]
            public IntPtr ncb_post;
            [FieldOffset(50)]
            public long ncb_reserve1;
            [FieldOffset(0x3a)]
            public short ncb_reserve2;
            [FieldOffset(1)]
            public byte ncb_retcode;
            [FieldOffset(0x2a)]
            public byte ncb_rto;
            [FieldOffset(0x2b)]
            public byte ncb_sto;

            public void init()
            {
                this.ncb_command = 0;
                this.ncb_retcode = 0;
                this.ncb_lsn = 0;
                this.ncb_num = 0;
                this.ncb_buffer = IntPtr.Zero;
                this.ncb_length = 0;
                this.ncb_callname1 = 0;
                this.ncb_callname2 = 0;
                this.ncb_name1 = 0L;
                this.ncb_name2 = 0L;
                this.ncb_rto = 0;
                this.ncb_sto = 0;
                this.ncb_post = IntPtr.Zero;
                this.ncb_lana_num = 0;
                this.ncb_cmd_cplt = 0;
                this.ncb_reserve1 = 0L;
                this.ncb_reserve2 = 0;
                this.ncb_event = 0;
            }
        }
    }
}

